#pragma once

#include "Compiler.hpp"
#include "Runner.hpp"
#include <jsoncpp/json/json.h>

namespace OJ
{
  class CompilerAndRunner
  {
  public:
    static std::string codeToDesc(int code)
    {
      std::string desc;
      switch (code)
      {
      case SIGABRT: // 6
        desc = "内存超过范围";
        break;
      case SIGXCPU: // 24
        desc = "CPU使用超时";
        break;
      case SIGFPE: // 8
        desc = "浮点数溢出";
        break;
      default:
        desc = "未知: " + std::to_string(code);
        break;
      }
      return desc;
    }
    static void start(const std::string &json_in, std::string &json_out)
    {
      Json::Value value_in;
      Json::Reader reader;

      // 将输入的json解析
      reader.parse(json_in, value_in);
      std::string code = value_in["code"].asString();
      std::string input = value_in["input"].asString();
      int limit_cup = value_in["limit_cup"].asInt();
      int limit_memory = value_in["limit_memory"].asInt();

      // 检查代码是否为空
      if (code.empty())
      {
        Json::Value value_out;
        value_out["status"] = -1;
        value_out["reason"] = "提交的代码是空";
        Json::FastWriter writer;
        json_out = writer.write(value_out);
        return;
      }

      // 生成临时文件
      std::string file_name = Tool::FileHandler::creatUniqueFileName();

      if (!Tool::FileHandler::writeFile(Tool::PathBuilder::buildSourcePath(file_name), code))
      {
        Json::Value value_out;
        value_out["status"] = -2;
        value_out["reason"] = "未知错误";
        Json::FastWriter writer;
        json_out = writer.write(value_out);
        Tool::FileHandler::removeFile(file_name);
        return;
      }

      // 编译
      if (!OJ::Compiler::compile(file_name))
      {
        // 编译失败的错误处理
        Json::Value value_out;
        value_out["status"] = -3;
        std::string str_err;
        value_out["reason"] = Tool::FileHandler::readFile(Tool::PathBuilder::buildCompileErrorPath(file_name), str_err, true);
        Json::FastWriter writer;
        json_out = writer.write(value_out);
        Tool::FileHandler::removeFile(file_name);
        return;
      }

      // 运行
      int ret = OJ::Runner::run(file_name, limit_cup, limit_memory);

      if (ret < 0)
      {
        // 内部错误
        Json::Value value_out;
        value_out["status"] = -2;
        value_out["reason"] = "未知错误";
        Json::FastWriter writer;
        json_out = writer.write(value_out);
        Tool::FileHandler::removeFile(file_name);
        return;
      }
      else if (ret == 0)
      {
        // 运行成功
        Json::Value value_out;
        value_out["status"] = 0;
        value_out["reason"] = "运行成功";
        std::string str_std;
        Tool::FileHandler::readFile(Tool::PathBuilder::buildStdOutPath(file_name), str_std, true);
        value_out["stdout"] = str_std;
        std::string str_err;
        Tool::FileHandler::readFile(Tool::PathBuilder::buildStdErrPath(file_name), str_err, true);
        value_out["stderr"] = str_err;
        Json::FastWriter writer;
        json_out = writer.write(value_out);
        Tool::FileHandler::removeFile(file_name);
        return;
      }
      else
      {
        // 运行时出错
        Json::Value value_out;
        value_out["status"] = ret;
        value_out["reason"] = codeToDesc(ret);
        Json::FastWriter writer;
        json_out = writer.write(value_out);
        Tool::FileHandler::removeFile(file_name);
        return;
      }
    }
  };
}